﻿using Newtonsoft.Json;
using Org.BouncyCastle.Utilities;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Zocono.Infrastructure.Common;
using Zocono.WCS.Comm;
using Zocono.WCS.Domain.DomainRepository;
using Zocono.WCS.Domain.EntityInfo;
using Zocono.WCS.Domain.FSJDomain;
using Zocono.WCS.Domain.LogDomain;
using Zocono.WCS.Domain.PlcBytesObject;
using Zocono.WCS.Domain.PlcConnectPoolDomain;
using Zocono.WCS.Domain.ProcessModuleDomain;
using Zocono.WCS.Infrastructure.ApllicationDto.DtoWcsManage;
using Zocono.WCS.Infrastructure.ApllicationDto.WCSTaskDto;
using Zocono.WCS.WMSApiDomain.WebApi;

namespace Zocono.WCS.Domain.EquipmentProcessDomain.PlanarGeneralMessage
{
    /// <summary>
    /// 跳过当前流程节点
    /// </summary>
    public class DrumpOutProcessService : IPlanarGeneralPlcActionProcessService
    {
        private readonly IRedisHelper _IRedisHelper;
        private readonly ILogUtil _LogUtil;
        private readonly IPlcConnectionPool _PlcConnectionPool;
        private readonly IWorkTaskInfoRepository _WorkTaskInfoRepository;
        private readonly IPlcWriteDbInfoRepository _PlcWriteDbInfoRepository;
        private readonly IPlcConnectionInfoRepository _PlcConnectionInfoRepository;
        private readonly IPlcPointInfoRepositpry _IPlcPointInfoRepositpry;
        private readonly IPlcConnectionStateInfoRepository _IPlcConnectionStateInfoRepository;
        private readonly IRunLogInfoService _IRunLogInfoService;
        private readonly IPlcReadDbInfoRepository _PlcReadDbInfoRepository;
        private readonly IInterfaceLogInfoService _InterfaceLogInfoService;
        private readonly IFSJMesService _IFSJMesService;

        public DrumpOutProcessService(IRedisHelper iRedisHelper, ILogUtil logUtil
            , IPlcConnectionPool plcConnectionPool
            , IWorkTaskInfoRepository workTaskInfoRepository
            , IPlcWriteDbInfoRepository plcWriteDbInfoRepository
            , IPlcConnectionInfoRepository plcConnectionInfoRepository,
            IPlcPointInfoRepositpry plcPointInfoRepositpry
             , IPlcConnectionStateInfoRepository plcConnectionStateInfoRepository
            , IRunLogInfoService runLogInfoService,
             IPlcReadDbInfoRepository plcReadDbInfoRepository,
             IInterfaceLogInfoService iterfaceLogInfoService,
            IFSJMesService iFSJMesService//,
                                         // AisleRequestService aisleRequestService
            )
        {
            _IRedisHelper = iRedisHelper;
            _LogUtil = logUtil;
            _PlcConnectionPool = plcConnectionPool;
            _WorkTaskInfoRepository = workTaskInfoRepository;
            _PlcWriteDbInfoRepository = plcWriteDbInfoRepository;
            _PlcConnectionInfoRepository = plcConnectionInfoRepository;
            _IPlcPointInfoRepositpry = plcPointInfoRepositpry;
            _IPlcConnectionStateInfoRepository = plcConnectionStateInfoRepository;
            _IRunLogInfoService = runLogInfoService;
            _PlcReadDbInfoRepository = plcReadDbInfoRepository;
            _InterfaceLogInfoService = iterfaceLogInfoService;
            _IFSJMesService = iFSJMesService;
        }

        public async Task ProcessActionMessageAsync(BytesObjectBase plcActionMessage, BytesObjectBase wcsActionMessage, EquipmentDbObject planarEquipmentDbObject/*, BytesObjectBase plcStateMassge*/)
        {
           /*
            * 处理逻辑
            * 1. 验证plc是否在线
            * 2. 验证当前设备是否报警
            * 3. 验证wcs任务，验证wcs当前子任务(待执行、执行中)，当前子任务已经是SC完成后更新了
            * 4. 组织plc报文，写入plc
            */

            var plcMessage = plcActionMessage as PlanarGeneralPlcActionBO;//Plc的动作报文
            var wcsMessage = wcsActionMessage as PlanarGeneralWcsActionBO;//Wcs的动作报文
            plcMessage.PalletBarcode = plcMessage.PalletBarcode.Trim();


            var ContainerBarcode = plcMessage.PalletBarcode.Trim();
            var EquipmentCode = plcMessage.EquipmentCode.Trim();

            //交互位写入
            var objectType = typeof(PlanarGeneralWriteWcsAction).Name;
            var writeConfig = await _PlcWriteDbInfoRepository.GetFirstAsync(it => it.EquipmentCode == plcMessage.EquipmentCode && it.ObjectType == objectType);

            PlanarGeneralWriteWcsAction writeBo = new PlanarGeneralWriteWcsAction(
                writeConfig.PlcConnectionId,
                writeConfig.ID,
                writeConfig.DbCode,
                writeConfig.DbStart,
                objectType,
                plcMessage.EquipmentCode.ToInt32(),
                0,
                0,
                0,
                ContainerBarcode,
                0,
                0);

            RunLogInfo runLogInfo = new RunLogInfo();
            runLogInfo.ContainerBarcode = plcMessage.PalletBarcode;
            runLogInfo.EquipmentCode = plcMessage.EquipmentCode;
            runLogInfo.RunType = "跳过当前流程节点";

            runLogInfo.RunLog = "跳过当前流程节点";


            var plcConn = _PlcConnectionPool.S7GetWritePlcConnection(plcMessage.PlcConnectionID);
            if (plcConn == null)
            {
                //runLogInfo.RunLog = $"获取连接({plcMessage.PlcConnectionID})失败";
                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                _LogUtil.Error($"跳过当前流程节点：托盘【{plcMessage.PalletBarcode}】跳过当前流程节点，PLC设备【{plcMessage.EquipmentCode}】,连接池无连接({plcMessage.PlcConnectionID})");
                return;
            }
            var plcIPStates = await _IPlcConnectionStateInfoRepository.GetFirstAsync(l => l.PlcConnectionID == plcMessage.PlcConnectionID && l.Connected == true);
            if (plcIPStates == null)
            {
                //runLogInfo.RunLog = $"{plcConn.IP}plc已离线";
                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                _LogUtil.Error($"跳过当前流程节点：托盘【{plcMessage.PalletBarcode}】跳过当前流程节点，PLC设备【{plcMessage.EquipmentCode}】,获取连接({plcMessage.PlcConnectionID})失败");
                return;
            }
            //if (plcMessage.AlrmCode != 0)
            //{
            //    runLogInfo.RunLog = $"报警,报警代码：{plcMessage.AlrmCode}";
            //    await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
            //    return;
            //}

            //校验plc信息是否有托盘码
            if (string.IsNullOrEmpty(plcMessage.PalletBarcode) || plcMessage.PalletBarcode.Length != 10)
            {
                writeBo.AlrmCode = 102;
                writeBo.ActionType = 99;
                var flag = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                _IRedisHelper.SetStringKey($"PLC-{plcMessage.EquipmentCode}", plcMessage.EquipmentCode.ToString() + plcMessage.AlrmCode, TimeSpan.FromSeconds(10));
                return;
            }

            try
            {
                //上报挑选完结果 单电芯解绑
                var upDataResult = await WCSMessageWithWMSApi.ExtentOutThisProcessAsync(plcMessage.PalletBarcode, plcMessage.EquipmentCode);
                //_LogUtil.Debug($"分选台挑选位:上报挑选完毕：【FX-{EquipmentCode}】请求参数-->{JsonHelper.SerializeObject(upInfo)}--->返回结果：{JsonHelper.SerializeObject(upDataResult)}");

                if (upDataResult.Result)
                {
                    writeBo.ActionType = plcMessage.ActionType;
                    var res = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                    if (res)
                    {
                        // 记录运行日志
                        runLogInfo.RunLog = $"跳过当前流程节点：托盘【{plcMessage.PalletBarcode}】跳过当前流程节点，PLC设备【{plcMessage.EquipmentCode}】跳过当前流程节点，写入报文成功！报文内容：{JsonConvert.SerializeObject(writeBo)}";
                        await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                    }
                }
                else
                {
                    writeBo.AlrmCode = 129;
                    writeBo.ActionType = 99;
                    var res = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                    _IRedisHelper.SetStringKey($"PLC-{plcMessage.EquipmentCode}", plcMessage.EquipmentCode.ToString() + plcMessage.AlrmCode, TimeSpan.FromSeconds(10));
                    _LogUtil.Error($"跳过当前流程节点：托盘【{plcMessage.PalletBarcode}】跳过当前流程节点，PLC设备【FX-{plcMessage.EquipmentCode}】,分跳过当前流程节点失败");
                }
                
            }
            catch (Exception ex)
            {
                writeBo.AlrmCode = 131;
                writeBo.ActionType = 99;
                var res = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                _IRedisHelper.SetStringKey($"PLC-{plcMessage.EquipmentCode}", plcMessage.EquipmentCode.ToString() + plcMessage.AlrmCode, TimeSpan.FromSeconds(10));
                _LogUtil.Error($"跳过当前流程节点：托盘【{plcMessage.PalletBarcode}】跳过当前流程节点，PLC设备【FX-{plcMessage.EquipmentCode}】,跳过当前流程节点报错EX={ex.Message}");
                return;
            }

        }
    }
}
